precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;

uniform float u_width;
uniform float u_height;

#define FIX(c) max(abs(c), 1e-5);

const float PI = 3.1415926535897932384626433832795;

vec4 weight4(float x)
{         
    vec4 sample = FIX(PI * vec4(1.0 + x, x, 1.0 - x, 2.0 - x));

    // Lanczos2. Note: we normalize below, so no point in multiplying by radius (2.0)
    vec4 ret = /*2.0 **/ sin(sample) * sin(sample / 2.0) / (sample * sample);

    // Normalize
    return ret / dot(ret, vec4(1.0));
}         

vec4 pixel(float xpos, float ypos, sampler2D s_p)
{
    return texture2D(s_p, vec2(xpos, ypos)).rgba;
}

vec4 line(float ypos, vec4 xpos, vec4 linetaps, sampler2D s_p)
{         
    return mat4(
        pixel(xpos.x, ypos, s_p),
        pixel(xpos.y, ypos, s_p),
        pixel(xpos.z, ypos, s_p),
        pixel(xpos.w, ypos, s_p)) * linetaps;
}
    

void main()                                            
{
       vec2 stepxy = vec2(1.0 / u_width, 1.0 / u_height);
        vec2 pos = v_texCoord.xy + stepxy * 0.5;
        vec2 f = fract(pos / stepxy);

        vec2 xystart = (-1.5 - f) * stepxy + pos;
        vec4 xpos = vec4(
            xystart.x,
            xystart.x + stepxy.x,
            xystart.x + stepxy.x * 2.0,
            xystart.x + stepxy.x * 3.0);

        vec4 linetaps   = weight4(f.x);
        vec4 columntaps = weight4(f.y);   


// final sum and weight normalization
   vec4 color = mat4(
            line(xystart.y                 , xpos, linetaps, s_texture),
            line(xystart.y + stepxy.y      , xpos, linetaps, s_texture),
            line(xystart.y + stepxy.y * 2.0, xpos, linetaps, s_texture),
            line(xystart.y + stepxy.y * 3.0, xpos, linetaps, s_texture)) * columntaps;
   gl_FragColor = color;
}
 
